package com.tsmti.activiti.service.impl;

import com.tsmti.activiti.entity.ExtendActNodeField;
import com.tsmti.activiti.entity.ExtendActNodeSet;
import com.tsmti.activiti.entity.ExtendActNodeUser;
import com.tsmti.activiti.service.ExtendActNodeFieldService;
import com.tsmti.activiti.service.ExtendActNodeSetService;
import com.tsmti.activiti.service.ExtendActNodeUserService;
import com.tsmti.activiti.utils.ActConstants;
import com.tsmti.activiti.utils.ActUtils;
import com.tsmti.core.common.constant.Constants;
import com.tsmti.core.common.constant.DictionaryGroupConstants;
import com.tsmti.core.common.service.impl.BaseServiceImpl;
import com.tsmti.core.exception.MyException;
import com.tsmti.core.util.ConvertUtil;
import com.tsmti.core.util.StringUtils;
import com.tsmti.util.DictionaryUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

/**
 * @Package：com.tsmti.activiti.service.impl
 * @Class：ExtendActNodeSetServiceImpl
 * @Description： TODO
 * @Author：zcw
 * @Date：Created in 2018/8/16 15:41
 * @Company:
 * @Version：
 * @Modified By:
 *
 */
@Service("extendActNodesetService")
@Transactional(rollbackFor = Exception.class)
public class ExtendActNodeSetServiceImpl extends BaseServiceImpl<ExtendActNodeSet> implements ExtendActNodeSetService {

	@Autowired
	private ExtendActNodeUserService extendActNodeUserService;
	@Autowired
	private ExtendActNodeFieldService extendActNodeFieldService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ExtendActNodeSet saveNode(ExtendActNodeSet actNodeset) throws IOException {
		if(StringUtils.isEmpty(actNodeset.getModelId())){
			throw new MyException("模型id不能为空!");
		}
		if(StringUtils.isEmpty(actNodeset.getNodeId())){
			throw new MyException("节点id不能为空!");
		}
		if(StringUtils.isEmpty(actNodeset.getActNodeType())){
			throw new MyException("节点类型不能为空!");
		}
		//节点类型为审批节点
		if(actNodeset.getActNodeType().equals(ActConstants.NodeType.EXAMINE.getValue())){
			//设置会签取消会签
			if(ActConstants.ActAction.MULIT.getValue().equals(actNodeset.getNodeAction())){
				try {
					ActUtils.setMultiInstance(actNodeset.getModelId(),actNodeset.getNodeId());
				} catch (Exception e) {
					e.printStackTrace();
					throw new MyException("设置会签失败");
				}
			}else {
				try {
					ActUtils.clearMultiInstance(actNodeset.getModelId(),actNodeset.getNodeId());
				} catch (Exception e) {
					e.printStackTrace();
					throw new MyException("取消会签失败");
				}
			}
			if(StringUtils.isEmpty(actNodeset.getId())){
				//保存节点信息
				save(actNodeset);
			}else {
				//更新
				//保存节点信息
				update(actNodeset);
				//保存审批用户 先根据nodeId删除节点相关的审批用户
				extendActNodeUserService.removeAllByProperty("nodeId",actNodeset.getNodeId());
			}
            //保存审批用户
            String[] userTypes = actNodeset.getUserTypes();
            String[] userIds = actNodeset.getUserIds();
            String userField = actNodeset.getUserField();
            List<ExtendActNodeUser> nodeUsers = new ArrayList<ExtendActNodeUser>();
			ExtendActNodeUser nodeUser = null;
            if(userIds !=null && userIds.length>0){
				for (int i=0;i<userIds.length;i++){
					nodeUser = new ExtendActNodeUser();
					nodeUser.setUserNo(userIds[i]);
					nodeUser.setUserType(userTypes[i]);
					nodeUser.setNodeId(actNodeset.getNodeId());
					nodeUsers.add(nodeUser);
				}
			}
			//表单字段
			if(!StringUtils.isEmpty(userField)) {
				nodeUser = new ExtendActNodeUser();
				nodeUser.setUserNo(userField);
				nodeUser.setUserType(ActConstants.ExamineType.BILLUSER.getValue());
				nodeUser.setNodeId(actNodeset.getNodeId());
				nodeUsers.add(nodeUser);
			}
			if(nodeUsers !=null && nodeUsers.size() >0){
				extendActNodeUserService.saveAll(nodeUsers);
			}
		}
		//分支条件连线
		if(actNodeset.getActNodeType().equals(ActConstants.NodeType.LINE.getValue())){
			//保存
			if(StringUtils.isEmpty(actNodeset.getId())){
				//保存节点信息
                actNodeset.setId(StringUtils.randomUUID());
				save(actNodeset);
			}else {
				//更新
				//保存节点信息
				update(actNodeset);
				//根据nodeId删除所有节点对应的连线条件
				extendActNodeFieldService.removeAllByProperty("nodeId",actNodeset.getNodeId());
			}
			//el条件 例如${day>3 && isagree==1}
			StringBuilder condition = new StringBuilder("${");
			if(actNodeset.getJudgList() != null && actNodeset.getJudgList().size() > 0){
				List<ExtendActNodeField> judgList = new ArrayList<>();
				int sort =0;
				for (ExtendActNodeField nodefield:actNodeset.getJudgList()){
					if(StringUtils.isEmpty(nodefield.getFieldName()) || StringUtils.isEmpty(nodefield.getRule())){
						continue;
					}
					Map<String, Object> map = tranceCode(nodefield);
					if(!StringUtils.isEmpty(nodefield.getElOperator())){
						condition.append(" "+map.get("elOperator")+" ");
					}
					condition.append(nodefield.getFieldName()).append(map.get("rule")).append(nodefield.getFieldVal());
					nodefield.setNodeId(actNodeset.getNodeId());
					nodefield.setSort(sort+"");
					sort++;
					judgList.add(nodefield);
				}
				extendActNodeFieldService.saveAll(judgList);
			}
			String judg = condition.append("}").toString();
			//添加条件
			ActUtils.setSequenceFlowCondition(actNodeset.getModelId(),actNodeset.getNodeId(),judg);
		}
		//节点类型为结束
		if(actNodeset.getActNodeType().equals(ActConstants.NodeType.END.getValue())){
			if(StringUtils.isEmpty(actNodeset.getId())){
				//保存节点信息
				actNodeset.setId(StringUtils.randomUUID());
				save(actNodeset);
			}else {
				//更新
				update(actNodeset);
			}
		}
		return actNodeset;
	}

	@Override
	public ExtendActNodeSet queryByNodeId(String nodeId) {
		DetachedCriteria nosetCriteria = DetachedCriteria.forClass(ExtendActNodeSet.class);
		nosetCriteria.add(Restrictions.eq("nodeId",nodeId));
		nosetCriteria.add(Restrictions.eq("delFlag",0));
		List<ExtendActNodeSet> nodeSetList =  list(nosetCriteria);
		if(nodeSetList != null && nodeSetList.size() >0){
			return nodeSetList.get(0);
		}
		return null;
	}

	@Override
	public ExtendActNodeSet queryByNodeIdModelId(String nodeId, String modelId) {
		DetachedCriteria nosetCriteria = DetachedCriteria.forClass(ExtendActNodeSet.class);
		nosetCriteria.add(Restrictions.eq("nodeId",nodeId));
		nosetCriteria.add(Restrictions.eq("modelId",modelId));
		nosetCriteria.add(Restrictions.eq("delFlag",0));
		List<ExtendActNodeSet> nodeSetList =  list(nosetCriteria);
		if(nodeSetList != null && nodeSetList.size() >0){
			return nodeSetList.get(0);
		}
		return null;
	}

	/**
	 * 将中文字符转换为el运算符
	 * @param nodeField
	 */
	private Map<String,Object> tranceCode(ExtendActNodeField nodeField){
		Map<String,Object> map = new HashMap<>(16);
		if(ConvertUtil.isNotEmpty(nodeField.getElOperator())){
			String operator = DictionaryUtils.getSelectCode(DictionaryGroupConstants.DICT_ACT_ELOPERATOR,nodeField.getElOperator());
			switch (operator){
				case "并且":
					map.put("elOperator","&&");break;
				case "或者":
					map.put("elOperator","||");break;
				default:
			}
		}
		if(ConvertUtil.isNotEmpty(nodeField.getRule())){
			String rule = DictionaryUtils.getSelectCode(DictionaryGroupConstants.DICT_ACT_JUDG,nodeField.getRule());
			switch (rule){
				case "大于":
					map.put("rule",">");break;
				case "大于等于":
					map.put("rule",">=");break;
				case "小于":
					map.put("rule","<");break;
				case "小于等于":
					map.put("rule","<=");break;
				case "等于":
					map.put("rule","==");break;
				default:
			}
		}
		return map;
	}

}
